#include "knn.h"

KNN::KNN(){
}

KNN::KNN(Data *data) : data(data){

}

KNN::KNN(Data *data, vector<float>  query) : data(data), query(query){

}

void KNN::setData(Data *data, vector<float>  query){
    this->data = data;
    this->query = query;
}

void KNN::setQuery(vector<float> query){
     this->query = query;
}

intvec KNN::getResult(){
   vector< vector<float> > numdata = data->getNumericalData();
   intvec result;
   int numDimensions = query.size();
   int k = 10;
   Mat knndata(numdata.size(), numDimensions, CV_32F);
   Mat knnquery(1, numDimensions, CV_32F);
   Mat indices;
   Mat dists;
   cv::flann::KDTreeIndexParams indexParams(5);
   cv::flann::Index kdtree(knndata, indexParams);

   //copy input to knn
   for(int i = 0 ; i < knndata.rows ; ++i)
       for(int j = 0 ; j < knndata.cols ; ++j)
           knndata.at<float>(i,j) = numdata[i][j];

   //copy query to knn query
   for(int row = 0 ; row < knnquery.rows ; row++)
       for(int col = 0 ; col < knnquery.cols ; col++)
       knnquery.at<float>(row,col) = query[col];

   // Invoke the knn search
   kdtree.knnSearch(knnquery, indices, dists, k, cv::flann::SearchParams(64));

   //copy result to vector
   for(int row = 0 ; row < indices.rows ; row++)
       for(int col = 0 ; col < indices.cols ; col++)
           result.push_back(indices.at<int>(row,col));

    //return result vector
    return result;
}
